package com.andkrup.easygame.config {
	import com.andkrup.easygame.game.commands.IGameCommand;	
	
	import flash.utils.getQualifiedClassName;	
	import flash.utils.getDefinitionByName;	
	
	import com.andkrup.serialization.IParser;	
	
	/**
	 * @author Andkrup
	 */
	public class XmlConfigParser implements IParser {
		public function decode(data:*) : Object{
			if(data is XML) {
				var xml:XML = (data as XML).children()[0] as XML;
				var xmlName:String = xml.name().toString();
				trace("XmlConfigParser:> decode() tag: "+xmlName);
				var xmlnodes:XMLList;
				var nodes:XML;
				var cls:Class;
				
				switch(xmlName){
					case "game":
						var gc : GameConfiguration = new GameConfiguration();
						xmlnodes = xml..param;
						var key:String;
						var val:*;
						for each(nodes in xmlnodes){
							key = String(nodes.@key);
							try{
								val = readValue(nodes.@value);
							}
							catch(err:Error){
								trace("XmlConfigParser:> decode() error decoding key: "+nodes.@key+", stacktrace:\n"+err.getStackTrace());
							}
							if(null!=key && null!=val){
								gc.setValue(key, val);
							}
						}
						return gc;
					case "keys":
						var kc : KeyConfiguration = new KeyConfiguration();
						xmlnodes = xml..cmd;
						var code:String;
						var cmd:IGameCommand;
						trace("XmlConfigParser:> decode() xmlnodes.len: "+xmlnodes.length()+", xmlnodes: "+xmlnodes);
						for each(nodes in xmlnodes){
							code = String(nodes.@code);
							try{
								cls = getDefinitionByName("com.andkrup.easygamemodern.commands."+nodes.@type) as Class;
								cmd = new cls() as IGameCommand;
							}
							catch(err:Error){
								trace("XmlConfigParser:> decode() error decoding command: "+nodes.@type+", stacktrace:\n"+err.getStackTrace());
							}
							trace("XmlConfigParser:> decode() cmd: "+cmd+", code: "+code);
							if(cmd && code){
								cmd.code = code;
								cmd.eventType = nodes.@event;
								kc.addCommand(cmd);
							}
						}
						return kc;
				}	
			
			}
			return null;
		}

		public function encode(data : Object):*{
			return null;
		}
		
		/**
		 * TODO: needs to support all primitives
		 */
		private function readValue(data:String):*{
			if(!isNaN(Number(data))){
				return Number(data);
			}
			else if(data.toLowerCase()=="false" || data.toLowerCase()=="true"){
				return data.toLowerCase()=="true";
			}
			else{
				return data;
			}
		}
	}
}
